package com.inspur.icity.bus.base.core.util;

import com.google.gson.Gson;
import com.inspur.icity.bus.base.core.gaoderesult.*;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by jn-dinggao on 2017/12/20.
 */
public class GaodeMapApi {

    /**
     * 高德地图 key
     */
    private static final String GAODE_KEY = "63a4b0b68bf2d9fb6567f6e3b83fa811";

    /**
     * 高德地图 公交路径规划 url
     */
    private static final String GAODE_TRANSIT_URL = "http://restapi.amap.com/v3/direction/transit/integrated";

    /**
     * 关键字搜索 url
     */
    private static final String GAODE_V3_PLACE_URL = "http://restapi.amap.com/v3/place/text";

    /**
     * 高德逆地理 url
     */
    private static final String GAODE_GEOCODE_REGEO_URL = "http://restapi.amap.com/v3/geocode/regeo";

    /**
     * 搜索提示 url
     */
    private static final String GAODE_INPUTTIPS_URL = "http://restapi.amap.com/v3/assistant/inputtips";

    /**
     * 查询POI类型 190000 地名地址信息
     */
    private static final String GAODE_POI_PLACE_TYPE = "190000";

    /**
     * 仅返回指定城市数据
     */
    private static final String GAODE_POI_PLACE_CITYLIMIT = "true";

    /**
     * 每页记录数据 默认10条
     */
    private static final String GAODE_POI_PLACE_OFFSET = "10";

    /**
     * 当前页数 默认第一页
     */
    private static final String GAODE_POI_PLACE_PAGE = "1";

    /**
     * 公交路径规划
     * @param origin 起点经纬度
     * @param destination 终点经纬度
     * @param city 支持市内公交换乘/跨城公交的起点城市，规则：城市名称/citycode
     * @param cityd 跨城公交规划必填参数。规则：城市名称/citycode
     * @param strategy 0：最快捷模式;1：最经济模式;2：最少换乘模式;3：最少步行模式;5：不乘地铁模式
     * @return
     */
    public static DirectionTransitResult directionTransit(String origin,String destination,String city,String cityd,String strategy){
        return directionTransit(origin,destination,city,cityd,strategy,"0");
    }

    /**
     * 公交路径规划
     * @param origin 起点经纬度
     * @param destination 终点经纬度
     * @param city 支持市内公交换乘/跨城公交的起点城市，规则：城市名称/citycode
     * @param cityd 跨城公交规划必填参数。规则：城市名称/citycode
     * @param strategy 0：最快捷模式;1：最经济模式;2：最少换乘模式;3：最少步行模式;5：不乘地铁模式
     * @param nightflag 是否计算夜班车,1:是；0：否
     */
    public static DirectionTransitResult directionTransit(String origin,String destination,String city,String cityd,String strategy,String nightflag){

        Map<String, String> params = new HashMap<String, String>();
        if (StringUtils.isEmpty(origin) || StringUtils.isEmpty(destination) || StringUtils.isEmpty(city)) {
            return null;
        }
        /**
         * strategy 默认0：较快捷
         */
        strategy = StringUtils.isEmpty(strategy) ? "0" : strategy;
        /**
         * nightflag 如果没值默认 0
         */
        nightflag = StringUtils.isEmpty(nightflag) ? "0":nightflag;

        try{
            params.put("city",URLEncoder.encode(city,"UTF-8"));
            params.put("cityd",URLEncoder.encode(cityd,"UTF-8"));
        }catch (Exception e){
            e.printStackTrace();
        }
        params.put("key",GAODE_KEY);
        params.put("origin",origin);
        params.put("destination",destination);
        params.put("strategy",strategy);
        params.put("nightflag",nightflag);
        String result = HttpRequest.sendGet(GAODE_TRANSIT_URL,initParams(params));
        Gson gson = new Gson();

        return gson.fromJson(result, DirectionTransitResult.class);
    }

    /**
     * 关键字搜索
     * @param keywords 搜索关键字
     * @param city 所在城市
     * @return
     */
    public static PlaceTextResult place(String keywords,String city) {
        Map<String, String> params = new HashMap<String, String>();
        if (StringUtils.isEmpty(keywords)) {
            return null;
        }
        params.put("key",GAODE_KEY);
        params.put("types",GAODE_POI_PLACE_TYPE);
        params.put("citylimit",GAODE_POI_PLACE_CITYLIMIT);
        params.put("offset",GAODE_POI_PLACE_OFFSET);
        params.put("page",GAODE_POI_PLACE_PAGE);
        try{
            params.put("keywords", URLEncoder.encode(keywords,"utf-8"));
            params.put("city",URLEncoder.encode(city,"utf-8"));
        }catch (Exception e){
            e.printStackTrace();
        }
        String result = HttpRequest.sendGet(GAODE_V3_PLACE_URL,initParams(params));
        Gson gson = new Gson();
        return gson.fromJson(result,PlaceTextResult.class);
    }

    /**
     * 输入提示
     */
    public static InputTipsResult search(String keywords,String city){
        Map<String,String> params = new HashedMap();
        params.put("key",GAODE_KEY);
        try {
            params.put("keywords",URLEncoder.encode(keywords,"utf-8"));
            params.put("city",URLEncoder.encode(city,"utf-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        params.put("datatype","all");
        String result = HttpRequest.sendGet(GAODE_INPUTTIPS_URL,initParams(params));
        System.err.println("result:"+result);
        Gson gson = new Gson();
        return gson.fromJson(result,InputTipsResult.class);
    }

    /**
     * 逆地理查询
     * @param lng 经度
     * @param lat 维度
     * @return
     */
    public static GaocodeRegeoResult geoRegeo(String lng,String lat){
        String location = lng + "," + lat;
        return geoRegeo(location);
    }

    /**
     * 逆地理查询
     * @param location 经纬度
     * @return
     */
    public static GaocodeRegeoResult geoRegeo(String location){
        Map<String, String> params = new HashMap<String, String>();
        params.put("key",GAODE_KEY);
        params.put("location",location);
        String result = HttpRequest.sendGet(GAODE_GEOCODE_REGEO_URL,initParams(params));
        if(!StringUtils.isEmpty(result)){
            if(result.contains("\"formatted_address\":[],")){
                result = result.replace("\"formatted_address\":[],","");
            }
        }
        Gson gson = new Gson();
        return gson.fromJson(result,GaocodeRegeoResult.class);
    }

    /**
     * 参数 Map --> String
     * @param params
     * @return
     */
    public static String initParams(Map<String, String> params) {
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (first) {
                first = false;
            } else {
                sb.append("&");
            }
            String key = entry.getKey();
            String value = entry.getValue();
            sb.append(key).append("=");
            if (!StringUtils.isEmpty(value)) {
                sb.append(value);
            }
        }
        return sb.toString();
    }

    /**
     * 计算两点之间距离
     * @param startLng
     * @param startLat
     * @param endLng
     * @param endLat
     * @return
     */
    public static double getDistance(String startLng, String startLat, String endLng, String endLat) {
        return getDistance(Double.valueOf(startLng),Double.valueOf(startLat),Double.valueOf(endLng),Double.valueOf(endLat));
    }

    /**
     * 计算两点之间距离
     * @param startLng
     * @param startLat
     * @param endLng
     * @param endLat
     * @return
     */
    public static double getDistance(Double startLng, Double startLat, Double endLng, Double endLat) {
        double lon1 = (Math.PI / 180) * startLng;
        double lon2 = (Math.PI / 180) * endLng;
        double lat1 = (Math.PI / 180) * startLat;
        double lat2 = (Math.PI / 180) * endLat;
        // 地球半径
        double R = 6371;
        // 两点间距离 km
        double d = Math.acos(Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1)) * R;
        return BigDecimal.valueOf(d * 1000).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
    }


    public static void main(String[] args) {
      /*  DirectionTransitResult directionTransitResult = directionTransit("117.118972,36.713017","117.131846,36.670621","济南","","","");
        System.out.println(directionTransitResult);*/

        /*PlaceTextResult result = place("浪潮","济南市");
        System.out.println(result);*/
        GaocodeRegeoResult gaocodeRegeoResult = geoRegeo("117.114998,36.713986");
        System.out.println(gaocodeRegeoResult);

    }
}
